package plp.funcoo.io;

import plp.funcoo.environment.compilation.CompilationEnvironment;
import plp.funcoo.environment.compilation.Environment;
import plp.funcoo.environment.execution.ExecutionContext;
import plp.funcoo.environment.execution.ExecutionEnvironment;
import plp.funcoo.exceptions.ClassAlreadyDeclared;
import plp.funcoo.exceptions.ClassNotDeclared;
import plp.funcoo.exceptions.MethodAlreadDeclared;
import plp.funcoo.exceptions.MethodNotDeclared;
import plp.funcoo.exceptions.ParameterNumberIncorrect;
import plp.funcoo.exceptions.ParameterTypeIncorrect;
import plp.funcoo.exceptions.VarAlreadyDeclared;
import plp.funcoo.exceptions.VarNotDeclared;
import plp.funcoo.expressions.Expression;
import plp.funcoo.types.PrimitiveType;
import plp.funcoo.util.Type;
import plp.funcoo.value.ValueList;

public class Write implements Expression{

	
	private Expression expression;
	
	public Write(Expression expression)
	{
		this.expression = expression;
	}

	@Override
	public ExecutionEnvironment evaluate(ExecutionEnvironment envi) throws VarNotDeclared, MethodNotDeclared, VarAlreadyDeclared, MethodAlreadDeclared {
		
		envi = this.expression.evaluate(envi);
		ValueList aux = ((ExecutionContext)envi).getValueOutput();
		aux.add(((ExecutionContext)envi).getValueAnalyzed());
		((ExecutionContext)envi).setValueOutput(aux);
		((ExecutionContext)envi).cleanExpression();
		return envi;
	}

	@Override
	public boolean typeCheck(CompilationEnvironment envi)
			throws VarAlreadyDeclared, VarNotDeclared, ClassAlreadyDeclared,
			ClassNotDeclared, MethodAlreadDeclared, MethodNotDeclared, ParameterTypeIncorrect, ParameterNumberIncorrect {
		
		return this.expression.typeCheck(envi);
	}

	@Override
	public Type getType(Environment envi) throws VarNotDeclared,
			ClassNotDeclared {
		
		return PrimitiveType.Type_VOID;
	}

	@Override
	public Expression makeCopy() {
		return new Write(expression.makeCopy());
	}
}
